<template>
  <div>
    <el-switch
        v-model="draggable"
        active-text="开启拖拽"
        inactive-text="关闭拖拽">
    </el-switch>
    <span style="">
    <el-button v-if="draggable" type="primary" round size="mini" @click="bathSave">
      批量保存
    </el-button>
    <el-button type="danger" round size="mini" @click="bathDelete">批量删除</el-button>
      </span>
    <el-tree :data="menus" :props="defaultProps"
             :expand-on-click-node="false" show-checkbox node-key="catId"
             :default-expanded-keys="expandedKey" :draggable="draggable" :allow-drop="allowDrop"
             @node-drop="handleDrop" ref="menutree">
    <span class="custom-tree-node" slot-scope="{ node, data }">
        <span>{{ node.label }}</span>
        <span>
          <el-button
              v-if="node.level<=2"
              type="text"
              size="mini"
              @click="() => append(data)">
            新增
          </el-button>
          <el-button
              type="text"
              size="mini"
              @click="() => edit(data)">
            编辑
          </el-button>
          <el-button
              v-if="node.childNodes.length==0"
              type="text"
              size="mini"
              @click="() => remove(node, data)">
            删除
          </el-button>
        </span>
      </span>
    </el-tree>


    <!--    新增/编辑弹框-->
    <el-dialog
        :title="titleName"
        :visible.sync="dialogVisible"
        width="30%" :close-on-click-modal="false"
        @close="vaciarData()">
      <el-form :model="category">
        <el-form-item label="分类名称">
          <el-input v-model="category.name" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="图标">
          <el-row>
            <el-col :span="24">
              <el-popover
                  ref="iconListPopover"
                  placement="bottom-start"
                  trigger="click"
                  popper-class="mod-menu__icon-popover">
                <div class="mod-menu__icon-inner">
                  <div class="mod-menu__icon-list">
                    <el-button
                        v-for="(item, index) in iconList"
                        :key="index"
                        @click="iconActiveHandle(item)"
                        :class="{ 'is-active': item === category.icon }">
                      <icon-svg :name="item"></icon-svg>
                    </el-button>
                  </div>
                </div>
              </el-popover>
              <el-input v-model="category.icon" v-popover:iconListPopover :readonly="true" placeholder="菜单图标名称"
                        class="icon-list__input"></el-input>
            </el-col>
          </el-row>
        </el-form-item>
        <el-form-item label="计量单位">
          <el-input v-model="category.productUnit" autocomplete="off"></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
    <el-button @click="cancel()">取 消</el-button>
    <el-button type="primary" @click="submitData">确 定</el-button>
  </span>
    </el-dialog>
  </div>
</template>

<script>
import da from "element-ui/src/locale/lang/da";
import {data} from "autoprefixer";
import Icon from '@/icons'

export default {
  data() {
    return {
      draggable: false,
      updateNudes: [],
      maxLevel: 0,
      pCid: [],
      menus: [],
      expandedKey: [],
      dialogVisible: false,
      titleName: undefined,
      dialogType: undefined,
      category: {
        catId: undefined,
        name: undefined,
        parentCid: 0,
        catLevel: 0,
        sort: 0,
        icon: undefined,
        productUnit: undefined,
        iconList: []
      },
      defaultProps: {
        children: 'children',
        label: 'name'
      }
    }
  },
  methods: {

    //查询所有分类
    getMenus() {
      this.$http({
        url: this.$http.adornUrl('/product/pmsCategory/list/tree'),
        method: 'get'
      }).then(({data}) => {
        if (data && data.code === 0) {
          console.log('成功获取菜单数据...', data.data)
          this.menus = data.data;
        } else {
          this.$message.error(data.msg);
        }
      })
    },

    //点击添加，弹出弹框
    append(data) {
      this.titleName = "新增菜单"
      this.dialogType = "add";
      //打开对话框
      this.dialogVisible = true;

      //赋父分类的值
      this.category.parentCid = data.catId;
      this.category.catLevel = data.catLevel * 1 + 1;
    },

    //添加三级分类
    addCategory() {
      this.$http({
        url: this.$http.adornUrl('/product/pmsCategory/save'),
        method: 'post',
        data: this.$http.adornData(this.category, false)
      }).then(({data}) => {
        if (data && data.code === 0) {
          this.$message({
            type: 'success',
            message: '添加菜单成功!'
          })
          //关闭对话框
          this.dialogVisible = false;
          //刷新数据
          this.getMenus();
          //设置默认要展开的菜单
          this.expandedKey = [this.category.parentCid]
          //清空数据
          this.vaciarData();
        } else {
          this.$message.error(data.msg)
        }
      });
    },

    // 删除分类
    remove(node, data) {
      this.$confirm(`是否删除【${data.name}】菜单`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        var ids = [data.catId]
        this.$http({
          url: this.$http.adornUrl('/product/pmsCategory/delete'),
          method: 'post',
          data: this.$http.adornData(ids, false)
        }).then(({data}) => {
          if (data && data.code === 0) {
            this.$message({
              type: 'success',
              message: '菜单删除成功!'
            })
            //刷新数据
            this.getMenus()
            //设置默认要展开的菜单
            this.expandedKey = [node.parent.data.catId]
          } else {
            this.$message.error(data.msg)
          }
        });
      }).catch(() => {

      });
    },

    //点击编辑，弹出弹框
    edit(data) {
      this.titleName = "编辑菜单";
      this.dialogType = "edit";
      //打开对话框
      this.dialogVisible = true;
      //赋原始对象值

      //发送请求查询获取当前阶段最新的数据
      this.$http({
        url: this.$http.adornUrl(`/product/pmsCategory/info/${data.catId}`),
        method: 'get',
        params: this.$http.adornParams({})
      }).then(({data}) => {
        this.category = data.data;
      })
    },

    //编辑三级分类
    editCategory() {
      this.$http({
        url: this.$http.adornUrl('/product/pmsCategory/update'),
        method: 'put',
        data: this.$http.adornData(this.category, false)
      }).then(({data}) => {
        if (data && data.code === 0) {
          this.$message({
            type: 'success',
            message: '更新菜单成功!'
          })
          //关闭对话框
          this.dialogVisible = false;
          //刷新数据
          this.getMenus();
          //设置默认要展开的菜单
          this.expandedKey = [this.category.parentCid]
          //清空数据
          this.vaciarData();
        } else {
          this.$message.error(data.msg)
        }
      });
    },

    //取消操作
    cancel() {
      this.dialogVisible = false;
      this.vaciarData();
    },

    //清空对象沉余数据
    vaciarData() {
      //清空category对象数据
      this.category.catId = undefined;
      this.category.name = undefined;
      this.category.catLevel = 0;
      this.category.parentCid = 0;
      this.category.sort = 0;
      this.category.icon = undefined;
      this.category.productUnit = undefined;
    },

    //数据提交类型
    submitData(data) {
      if (this.dialogType == "add") {
        this.addCategory();
      }
      if (this.dialogType == "edit") {
        this.editCategory();
      }
    },

    //限制节点拖拽位置
    allowDrop(draggingNode, dropNode, type) {
      //1、判断当前节点以及所在的父节点总层数不能大于3

      //当前正在拖动的节点+父节点所在的深度不大于3即可
      this.countNodeLevel(draggingNode);
      //计算当前节点的深度
      let deep = Math.abs(this.maxLevel - draggingNode.level) + 1;

      // 判断是否是拖动到某个节点里面
      if (type == "inner") {
        //判断当前节拖动到指定节点里面是否大于3
        return (deep + dropNode.level) <= 3;
      } else {
        //判断当前节点拖动到某个阶段前面或后面是否大于3
        return (deep + dropNode.parent.level) <= 3;
      }
    },

    //递归求最大节点
    countNodeLevel(node) {
      //找到所有子节点，求出最大深度
      if (node.childNodes != null && node.childNodes.length > 0) {
        for (let i = 0; i < node.childNodes.length; i++) {
          if (node.childNodes[i].level > this.maxLevel) {
            //递归得出最大深度
            this.maxLevel = node.childNodes[i].level;
          }
          this.countNodeLevel(node.childNodes[i]);
        }
      }
    },

    //拖拽成功后发送请求
    handleDrop(draggingNode, dropNode, dropType) {

      //1、获取当前父节点Id
      let pCid = 0;

      //用于保存当前拖拽节点的同级节点
      let siblings = null;

      //判断节点插入位置
      if (dropType == "before" || dropType == "after") {

        //如果是插入的某个节点后面或者前面则取它们父级id
        pCid = dropNode.parent.data.catId == undefined ? 0 : dropNode.parent.data.catId;

        //如果是拖拽到某个节点的前面或者后则取父级节点中的所有子节点
        siblings = dropNode.parent.childNodes;
      } else {

        //如果是插入到某个节点里面则取被插入节点的id
        pCid = dropNode.data.catId;

        //如果是插入入到某个节点则取被插入节点所有的子节点
        siblings = dropNode.childNodes;
      }

      //保存当前需要展开的父节点
      this.pCid.push(pCid);

      console.log("siblings", siblings)

      //2、当前节点的最新顺序
      for (let i = 0; i < siblings.length; i++) {
        //如果遍历是当前拖拽的节点
        if (siblings[i].data.catId == draggingNode.data.catId) {

          //保存当前节点的默认层级
          let catLevel = draggingNode.level;

          //判断当前节点层级是否发生变化
          if (siblings[i].level != draggingNode.level) {

            //如果发生变化则修改当前节点的层级和子节点层级
            catLevel = siblings[i].level;

            //修改子节点层级
            this.updateChilNodeLevel(siblings[i]);
          }

          //被拖拽节点不仅要改顺序还需要将原来父级id改成最新父级id
          this.updateNudes.push({catId: siblings[i].data.catId, sort: i, parentCid: pCid, catLevel: catLevel});

        } else {

          //同级节点只需要重新排序
          this.updateNudes.push({catId: siblings[i].data.catId, sort: i});
        }
      }

      this.maxLevel = 0;

    },

    //批量修改提交
    bathSave() {
      //数据不为空则提交请求
      if (this.updateNudes.length > 0) {
        //发送请求
        this.$http({
          url: this.$http.adornUrl('/product/pmsCategory/update/sort'),
          method: 'put',
          data: this.$http.adornData(this.updateNudes, false)
        }).then(({data}) => {

          if (data && data.code === 0) {
            this.$message({
              type: 'success',
              message: '更新菜单成功!'
            })
            //关闭对话框
            this.dialogVisible = false;
            //刷新数据
            this.getMenus();
            //设置默认要展开的菜单
            this.expandedKey = this.pCid
            //清空数据
            this.updateNudes = [];
            this.maxLevel = 0;
            // this.pCid = 0;
          } else {
            this.$message.error(data.msg)
          }
        });
      }
    },

    //批量删除
    bathDelete() {
      //用于保存选中元素的所有id
      let cadIds = [];

      //用于存取选中元素的所有名称
      let catName = [];

      //使用elementui内置的方法调取选中元素对象以数组返回
      let chekedNodes = this.$refs.menutree.getCheckedNodes();

      //遍历数组取元素id
      for (let i = 0; i < chekedNodes.length; i++) {
        //存取id
        cadIds.push(chekedNodes[i].catId);
        catName.push(chekedNodes[i].name);
      }

      if (cadIds.length > 0) {
        this.$confirm(`是否批量删除【${catName.slice(0, 5)}~~】菜单....`, '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          this.$http({
            url: this.$http.adornUrl('/product/pmsCategory/delete'),
            method: 'post',
            data: this.$http.adornData(cadIds, false)
          }).then(({data}) => {
            if (data && data.code === 0) {
              this.$message({
                type: 'success',
                message: '菜单批量删除成功!'
              })
              //刷新数据
              this.getMenus()
            } else {
              this.$message.error(data.msg)
            }
          });
        }).catch(() => {

        });
      }

    },

    //递归改变子节点的层级
    updateChilNodeLevel(node) {

      //判断是否存在子节点
      if (node.childNodes.length > 0) {
        for (let i = 0; i < node.childNodes.length; i++) {

          //获取子节点数据
          var cNode = node.childNodes[i].data;

          //更改子节点层级
          this.updateNudes.push({catId: cNode.catId, catLevel: node.childNodes[i].level})

          //当节点可能也会有子节点，进行递归修改
          this.updateChilNodeLevel(node.childNodes[i]);
        }
      }
    },

    // 图标选中
    iconActiveHandle(iconName) {
      this.category.icon = iconName
    }

  },
  created() {
    this.iconList = Icon.getNameList();
    this.getMenus()
  }
}
</script>

<style lang="scss">

.mod-menu {
  .icon-list__input {
    > .el-input__inner {
      cursor: pointer;
    }
  }

  &__icon-popover {
    width: 458px;
    overflow: hidden;
  }

  &__icon-inner {
    width: 478px;
    max-height: 258px;
    overflow-x: hidden;
    overflow-y: auto;
  }

  &__icon-list {
    width: 458px;
    padding: 0;
    margin: -8px 0 0 -8px;

    > .el-button {
      padding: 8px;
      margin: 8px 0 0 8px;

      > span {
        display: inline-block;
        vertical-align: middle;
        width: 18px;
        height: 18px;
        font-size: 18px;
      }
    }
  }

  .icon-list__tips {
    font-size: 18px;
    text-align: center;
    color: #e6a23c;
    cursor: pointer;
  }
}

</style>
